/**
 * 
 */
define(function(){
	var m_guid = '',
		m_url = undefined,
		m_format = 0,
		m_recordfilename = '',
		m_recordfileformat = 0,
		m_servername = '',
		m_reckeys = [],
		m_reckeysdata = {},

		m_CallInfo = {},
		myCallInfo = {},
		recstarttime = 0,
		recendtime = 0,

		m_UCID = '',
		m_recdat = 'ucid',

		m_recstrfield2 = "",
		m_strfield2 = "",
		m_recdats = [m_recdat],
		m_otherfields = {},
		m_sqlkey_record_insert = "",
		m_sqlkey_record_update = "",
		m_autorecordno = true;

	var Extra = function(project, params){
		this.project = project;
		this.name = 'ctiextra_ctirecording';
		m_url = project.getParam('RECPAT');
		m_format = project.getParam("RECFMT") || 0;
		//m_url = "http://10.1.24.171//[rec.mediano]?file=";
		if (!m_url) {
			m_url = '';
		} else {
			m_reckeys = findreckeys(m_url);
		}
		m_recdat = project.getParam('RECDAT');
		if (!m_recdat) {
			m_recdat = 'ucid';
			m_recdats = [m_recdat];
		} else {
			m_recdats = m_recdat.split('|');
		}

		m_recstrfield2 = project.getParam("RECST2");

		$SC.regcall(this.name, [["queryextra", this.queryCTICall]], params);
		$SC.addEvtListener(this.name, 'OnSCTIEvent', OnSCTIEvent, -1, params);
		$SC.addEvtListener(this.name, 'OnOrigCTIEvent', OnSCTIEvent, -1, params);
	};
	Extra.prototype = {
		queryCTICall: function (callName, callParams, callback) {
			if (callName.toLowerCase() === "queryextra" && callParams.callname === "setrecord") {
				var props = callParams.params.split("|");
				for (let i = 0; i < props.length; i++) {
					var oneprop = props[i].split("=");
					if (oneprop.length > 1) {
						switch (oneprop[0].toLowerCase()) {
							case "record_guid":
								break;
							case "bussinesstype1" :
							case "businesstype1":
								m_otherfields.businesstype1 = oneprop[1];
								break;
							case "bussinesstype2" :
							case "businesstype2":
								m_otherfields.businesstype2 = oneprop[1];
								break;
							case "stringfield1" :
								addconsolelog("stringfield1 is used for ctiType");
								break;
							case "stringfield2":
							case "stringfield3":
							case "stringfield4":
							case "stringfield5":
							case "stringfield6":
							case "stringfield7":
							case "stringfield8":
							case "stringfield9":
							case "stringfield10":
								m_otherfields[oneprop[0].toLowerCase()] = oneprop[1];
								break;
							default :
								addconsolelog("unsupported setrecord field " + oneprop[0]);
								break;
						}
					}
				}
				OnSCTIEvent("setrecord");
			}
		}
	};

	function findreckeys(s) {
		var keys = [];
		var i = s.indexOf("[");
		var j;
		if (i>=0) {
			j = s.indexOf("]", i+2);
		}
		while (i>=0 && j>=0) {
			var s1 = s.substr(i+1, j-i-1).toLowerCase();
			if (s1.startsWith("rec.")) {
				keys.push(s1.substr(4));
			}
			i = s.indexOf("[", j+1);
			if (i>=0) {
				j = s.indexOf("]", i+2);
			}
		}
		return keys;
	};

	function addconsolelog(s) {
		$SC.addconsolelog("[ctiextra_ctirecording]" + s);
	}

	function OnSCTIEvent(evt){
		var evtname = '';
		var bOrigCTIEvent = false;
		var calltype = 0;

		if (typeof(evt)=='string') {
			evtname = evt.toLowerCase();
		} else {
			evtname = evt.event.value.toString().toLowerCase();
			bOrigCTIEvent = true;
		}
		switch(evtname){
			case 'onlogin':
				m_sqlkey_record_insert = $SC._getconfig("CTISave", "sqlkey_record_insert") || "softphone.extra.record.insert.v202008";
				m_sqlkey_record_update = $SC._getconfig("CTISave", "sqlkey_record_update") || "softphone.extra.record.update.v202008";
				if (m_sqlkey_record_insert >= "softphone.extra.record.insert.v202008") {
					m_autorecordno = true;
				}
				m_recfmt = $SC._getconfig("RECORD", "RECFMT");
				if (m_recfmt != undefined) {
					m_recordfileformat = m_recfmt;
				} else {
					m_recordfileformat = m_format;
				}
				if (!m_recordfileformat) {
					m_recordfileformat = 0;
				}
				break;
			case 'oncallstart':
				myCallInfo = $SC.CallInfo;
				m_guid = '';
				m_recordfilename = '';
				recstarttime = 0;
				recendtime = 0;

				m_UCID = '';
				break;
		case 'oncallestablish':
			getuserdata();
			break;
		case 'oncallend':
			if (!m_UCID) {
				getuserdata();
			}
			m_CallInfo = {};
			m_CallInfo.m_Event = {};

			m_CallInfo.m_Event.calltype = $SC.CallInfo.m_Event.calltype;
			m_CallInfo.m_Event.customer_guid = $SC.CallInfo.m_Event.customer_guid;
			m_CallInfo.m_Event.customername = $SC.CallInfo.m_Event.customername;

			m_CallInfo.CallType = $SC.CallInfo.CallType;
			m_CallInfo.DNIS = $SC.CallInfo.DNIS;
			m_CallInfo.ANI = $SC.CallInfo.ANI;
			m_CallInfo.StartTime = $SC.CallInfo.StartTime;
			m_CallInfo.EstablishTime = $SC.CallInfo.EstablishTime;
			m_CallInfo.EndTime = $SC.CallInfo.EndTime;
			m_CallInfo.hangupType = $SC.CallInfo.hangupType;
			m_CallInfo.Event_GUID = $SC.CallInfo.Event_GUID;

			//$SC.CallInfo.AttachData

			break;
		case '77':
		//case 'evt_77':
			if (!bOrigCTIEvent) {
				break;
			}

			if ($SC.CallInfo.monitorcall) {
				addconsolelog("ignore " + evtname + " for monitorcall " + $SC.CallInfo.monitorcall);
				break;
			}

			if (!m_UCID) {
				getuserdata();
			}
	//softphone.extra.record.insert.v201610=INSERT INTO Record{C1}(Record_GUID,DNIS,ANI,StartTime,EndTime,Staff_ID,Agent_ID,Extension,HostName,CallType,HangupType,DocumentPath,FileFormat,Rolegroup_ID,MProject_ID,Customer_GUID,CustomerName,InitCallID,Event_GUID) values(@{C2}S,@{C3}S,@{C4}S,@{C5}D,@{C6}D,@{C7}S,@{C8}S,@{C9}S,@{C10}S,@{C11}N,@{C12}N,@{C13}S,@{C14}N,@{C15}S,@{C16}S,@{C17}S,@{C18}S,@{C19}S,@{C20}S)
			m_guid = Guid.raw();
			//m_Record.rec_guid = m_guid;
			var mproject_id = $E.getActiveProject().id;
			if (mproject_id.length > 6) {
				mproject_id = mproject_id.substr(0, 6);
			}
			var recordno = 0;
			if (!m_autorecordno) {
				if ($E.getActiveProject().getDbType() == "ORACLE") {
					try {
						var r = $SC.executeselectsql("softphone.extra.record.recordno.v201610");
						if (r.code >0) {
							recordno = r.value[0].fields[0][0];
						}
					} catch (err) {

					}
				}
			}
			data = {};
			m_otherfields = {};
			m_otherfields.stringfield1 = $SC.ctiType;
			if (evt.userdata && evt.userdata.value && evt.userdata.value.recordfilename) {
				m_recordfilename = evt.userdata.value.recordfilename.value;
				for (let i=0; i<m_reckeys.length; i++) {
					//rec.xxx
                    if (evt.userdata.value[m_reckeys[i]]) {
                        m_reckeysdata[m_reckeys[i]] = evt.userdata.value[m_reckeys[i]].value || '';
                    } else {
                        m_reckeysdata[m_reckeys[i]] = '';
                    }
				}
			} else {
				m_recordfilename = '';
			}


			if (evt.userdata && evt.userdata.value && evt.userdata.value.servername) {
				m_servername = evt.userdata.value.servername.value;
			} else {

			}
			if (evt.userdata && evt.userdata.value && evt.userdata.value.recordfileformat) {
				m_recordfileformat = evt.userdata.value.recordfileformat.value;
			} else {
				//m_recordfileformat = m_format;
			}

			m_strfield2 = "";
			if (m_recstrfield2) {
				if (evt && evt.userdata && evt.userdata.value[m_recstrfield2]) {
					m_strfield2 = evt.userdata.value[m_recstrfield2].value;
				} else {
					m_strfield2 = $SC.CallInfo.AttachData(m_recstrfield2);
				}
				if (m_strfield2) {
					m_otherfields.stringfield2 = m_strfield2;
				}
			}

			m_otherfields.businesstype1 = $SC.CallInfo.AttachData("mediatype") || "";

			myCallInfo = $SC.CallInfo;
			if (!myCallInfo.StartTime) {
				addconsolelog("CallInfos by my cache");
				myCallInfo = m_CallInfo;
			}

			if (evt.userdata && evt.userdata.value && evt.userdata.value.begintime) {
				recstarttime = new Date(evt.userdata.value.begintime.value).format("yyyy-MM-dd hh:mm:ss");
			} else {
				recstarttime = myCallInfo.EstablishTime;
			}
			if (evt.userdata && evt.userdata.value && evt.userdata.value.endtime) {
				recendtime = new Date(evt.userdata.value.endtime.value).format("yyyy-MM-dd hh:mm:ss");
			} else if (evt.userdata && evt.userdata.value && evt.userdata.value.begintime) {
				recendtime = recstarttime;
			} else {
				recendtime = myCallInfo.EndTime;
			}

			if (myCallInfo.m_Event) {
				calltype = myCallInfo.m_Event.calltype;
			}
			if (!calltype) {
				calltype = (myCallInfo.CallType == "3") ? 2 : 1;
			}
			$SC.executeupdatesql(m_sqlkey_record_insert, [$E.staff.epidSql, m_guid, $SC.getdbmask(myCallInfo.DNIS, "record", "dnis"), $SC.getdbmask(myCallInfo.ANI, "record", "ani"), recstarttime, recendtime
				, $E.staff.id, $SC.agentId, $SC.dn, "", calltype
				, myCallInfo.hangupType, replaceRecPath(m_url, m_recordfilename), m_recordfileformat
				, $E.staff.current.groupId, mproject_id, myCallInfo.m_Event.customer_guid, myCallInfo.m_Event.customername
				, m_UCID, myCallInfo.Event_GUID, recordno, $SC.getdbenc(myCallInfo.ANI), $SC.getdbenc(myCallInfo.DNIS)
				, m_otherfields.businesstype1, m_otherfields.businesstype2,m_otherfields.stringfield1,m_otherfields.stringfield2
				,m_otherfields.stringfield3,m_otherfields.stringfield4,m_otherfields.stringfield5,m_otherfields.stringfield6,m_otherfields.stringfield7
				,m_otherfields.stringfield8,m_otherfields.stringfield9,,m_otherfields.stringfield10,myCallInfo.StartTime]);

			/*
			$SC.executeupdatesql("softphone.extra.record.insert.v201610", [$E.staff.epidSql, m_guid, $SC.CallInfo.DNIS, $SC.CallInfo.ANI, $SC.CallInfo.EstablishTime || $SC.CallInfo.StartTime, $SC.CallInfo.EndTime
			                                                               , $E.staff.id, $SC.agentId, $SC.dn, '', ($SC.CallInfo.CallType == '3') ? 2 : 1
			                                                               , $SC.CallInfo.hangupType, replaceRecPath(m_url) + m_recordfilename, m_recordfileformat
			                                                               , $E.staff.current.groupId, mproject_id, $SC.CallInfo.m_Event.customer_guid, $SC.CallInfo.m_Event.customername
			                                                               , m_UCID, $SC.CallInfo.Event_GUID, recordno]);
			 */
			$SC.setRecordInfo({recording_guid : m_guid, recording_state : 1, recording_file : replaceRecPath(m_url, m_recordfilename), recording_starttime: recstarttime, recording_endtime: recendtime});
			break;
		case '78':
		//case 'evt_78':
		case 'saveevent':
		case 'setrecord':
			if (evtname === '78' && !bOrigCTIEvent) {
				break;
			}
				if (!m_UCID) {
					getuserdata();
				}
//softphone.extra.record.insert.v202008=INSERT INTO Record{C1}(Record_GUID,DNIS,ANI,StartTime,EndTime,Staff_ID,Agent_ID,Extension,HostName,CallType,HangupType,DocumentPath,FileFormat,Rolegroup_ID,MProject_ID,Customer_GUID,CustomerName,InitCallID,Event_GUID,ANI_ENC,DNIS_ENC,BUSSINESSTYPE1,BUSSINESSTYPE2,STRINGFIELD1,STRINGFIELD2) values(@{C2}S,@{C3}S,@{C4}S,@{C5}D,@{C6}D,@{C7}S,@{C8}S,@{C9}S,@{C10}S,@{C11}N,@{C12}N,@{C13}S,@{C14}N,@{C15}S,@{C16}S,@{C17}S,@{C18}S,@{C19}S,@{C20}S,@{C22}S,@{C23}S,@{C24}S,@{C25}S,@{C26}S,@{C27}S)
//softphone.extra.record.update.v202008=update Record{C1} set DNIS=@{C3}S,ANI=@{C4}S,StartTime=@{C5}D,EndTime=@{C6}D,CallType=@{C7}S,HangupType=@{C8}N,DocumentPath=@{C9}S,InitCallID=@{C10}S,Customer_GUID=@{C11}S,CustomerName=@{C12}S,Event_GUID=@{C13}S,BUSSINESSTYPE1=@{C14}S,BUSSINESSTYPE2=@{C15}S,STRINGFIELD1=@{C16}S,STRINGFIELD2=@{C17}S where record_guid=@{C2}S
//softphone.extra.record.update.v202008: @{C18}S: agentid, @{C19}S: dn, @{C20}S: ucid
			if (m_guid) {
				if (m_recstrfield2) {
					m_strfield2 = $SC.CallInfo.AttachData(m_recstrfield2);
					if (m_strfield2) {
						m_otherfields.stringfield2 = m_strfield2;
					}
				}
				if (!m_otherfields.businesstype1 || m_otherfields.businesstype1 == "undefined") {
					m_otherfields.businesstype1 = "";
				}
				if (!m_otherfields.businesstype2 || m_otherfields.businesstype2 == "undefined") {
					m_otherfields.businesstype2 = "";
				}
				if (!m_otherfields.stringfield1 || m_otherfields.stringfield1 == "undefined") {
					m_otherfields.stringfield1 = "";
				}
				if (!m_otherfields.stringfield2 || m_otherfields.stringfield2 == "undefined") {
					m_otherfields.stringfield2 = "";
				}
				if (!m_otherfields.stringfield3 || m_otherfields.stringfield3 == "undefined") {
					m_otherfields.stringfield3 = "";
				}
				if (!m_otherfields.stringfield4 || m_otherfields.stringfield4 == "undefined") {
					m_otherfields.stringfield4 = "";
				}
				if (!m_otherfields.stringfield5 || m_otherfields.stringfield5 == "undefined") {
					m_otherfields.stringfield5 = "";
				}
				if (!m_otherfields.stringfield6 || m_otherfields.stringfield6 == "undefined") {
					m_otherfields.stringfield6 = "";
				}
				if (!m_otherfields.stringfield7 || m_otherfields.stringfield7 == "undefined") {
					m_otherfields.stringfield7 = "";
				}
				if (!m_otherfields.stringfield8 || m_otherfields.stringfield8 == "undefined") {
					m_otherfields.stringfield8 = "";
				}
				if (!m_otherfields.stringfield9 || m_otherfields.stringfield9 == "undefined") {
					m_otherfields.stringfield9 = "";
				}
				if (!m_otherfields.stringfield10 || m_otherfields.stringfield10 == "undefined") {
					m_otherfields.stringfield10 = "";
				}


				myCallInfo = $SC.CallInfo;
				if (!myCallInfo.StartTime) {
					addconsolelog("CallInfos by my cache");
					myCallInfo = m_CallInfo;
				}

				if (evtname === "77" || evtname === "78") {
					if (evt.userdata && evt.userdata.value && evt.userdata.value.begintime) {
						recstarttime = new Date(evt.userdata.value.begintime.value).format("yyyy-MM-dd hh:mm:ss");
					} else {
						recstarttime = recstarttime || myCallInfo.EstablishTime;
					}
					if (evt.userdata && evt.userdata.value && evt.userdata.value.endtime) {
						recendtime = new Date(evt.userdata.value.endtime.value).format("yyyy-MM-dd hh:mm:ss");
					} else if (evt.userdata && evt.userdata.value && evt.userdata.value.begintime) {
						recendtime = recstarttime;
					} else {
						recendtime = myCallInfo.EndTime;
					}
					if (evt.userdata && evt.userdata.value && evt.userdata.value.recordfilename) {
						m_recordfilename = evt.userdata.value.recordfilename.value;
						for (let i=0; i<m_reckeys.length; i++) {
							//rec.xxx
							if (evt.userdata.value[m_reckeys[i]]) {
								m_reckeysdata[m_reckeys[i]] = evt.userdata.value[m_reckeys[i]].value || '';
							} else {
								m_reckeysdata[m_reckeys[i]] = m_reckeysdata[m_reckeys[i]] || '';
							}
						}
					}
				}

				//$SC.executeupdatesql("softphone.extra.record.update", [$E.staff.epidSql, m_guid, $SC.CallInfo.DNIS, $SC.CallInfo.ANI, $SC.CallInfo.EstablishTime || $SC.CallInfo.StartTime, $SC.CallInfo.EndTime, ($SC.CallInfo.CallType == '3') ? 2 : 1
				//                                                       , $SC.CallInfo.hangupType, replaceRecPath(m_url) + m_recordfilename, m_UCID, $SC.CallInfo.m_Event.customer_guid, $SC.CallInfo.m_Event.customername, $SC.CallInfo.Event_GUID]);
				if (myCallInfo.m_Event) {
					calltype = myCallInfo.m_Event.calltype;
				}
				if (!calltype) {
					calltype = (myCallInfo.CallType == "3") ? 2 : 1;
				}

				//$SC.executeupdatesql(m_sqlkey_record_update, [$E.staff.epidSql, m_guid, $SC.getdbmask(myCallInfo.DNIS, "record", "dnis"), $SC.getdbmask(myCallInfo.ANI, "record", "ani"), recstarttime, myCallInfo.EndTime, calltype
				//	, myCallInfo.hangupType, replaceRecPath(m_url, m_recordfilename), m_UCID, myCallInfo.m_Event.customer_guid, myCallInfo.m_Event.customername, myCallInfo.Event_GUID
				//	, m_otherfields.businesstype1, m_otherfields.businesstype2,m_otherfields.stringfield1,m_otherfields.stringfield2, $SC.agentId, $SC.dn]);

				$SC.executeupdate(m_sqlkey_record_update, [$E.staff.epidSql, m_guid, $SC.getdbmask(myCallInfo.DNIS, "record", "dnis"), $SC.getdbmask(myCallInfo.ANI, "record", "ani"), recstarttime, recendtime, calltype
					, myCallInfo.hangupType, replaceRecPath(m_url, m_recordfilename), m_UCID, myCallInfo.m_Event.customer_guid, myCallInfo.m_Event.customername, myCallInfo.Event_GUID
					, m_otherfields.businesstype1, m_otherfields.businesstype2,m_otherfields.stringfield1,m_otherfields.stringfield2, $SC.agentId, $SC.dn,m_UCID
					,m_otherfields.stringfield3,m_otherfields.stringfield4,m_otherfields.stringfield5,m_otherfields.stringfield6,m_otherfields.stringfield7
					,m_otherfields.stringfield8,m_otherfields.stringfield9,m_otherfields.stringfield10,myCallInfo.StartTime], function(data) {
						addconsolelog("record.update: " + data);
				});
				$SC.setRecordInfo({recording_guid : m_guid, recording_state : (myCallInfo.CallState2 > 0)?1:0, recording_file : replaceRecPath(m_url, m_recordfilename), recording_starttime: recstarttime, recording_endtime: recendtime});
			}
			break;
		}
	}

	function getuserdata() {
		if (m_recdats.length > 0) {
			for (var i=0; i<m_recdats.length; i++)
			{
				m_UCID = $SC.CallInfo.AttachData(m_recdats[i]);
				if (m_UCID) {
					break;
				}
			}
		}
		if (!m_UCID && m_recdats.length <=1 && m_recdat.toLowerCase() != 'ucid') {
			m_UCID = $SC.CallInfo.AttachData('ucid');
		}
	}
	
	function replaceRecPath(recpath, recfile){
		if (recfile && recfile.toLowerCase().startsWith("http")) {
			return recfile;
		}
		if (recpath) {
			if (!recfile) {
				recfile = "";
			}
			var s = recpath.replace(/\[UCID\]/gi, m_UCID);
			s = s.replace(/\[StartTime\]/gi, myCallInfo.EstablishTime);
			s = s.replace(/\[EndTime\]/gi, myCallInfo.EndTime);
			s = s.replace(/\[AgentID\]/gi, $SC.agentId);
			s = s.replace(/\[Extension\]/gi, $SC.dn);
			s = s.replace(/\[ServerName]/gi, m_servername);
			for (let x in m_reckeysdata) {
				s = s.replace(new RegExp("\\[rec."+x+"\\]", "gi"), m_reckeysdata[x]);
			};
			return s + recfile;
		} else {
			return recfile;
		}
	}

	return Extra; 
});